{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fd8c150d-eb14-4bed-9e51-094027096e23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "给出每个输入词的反义词\n",
      "\n",
      "原词：happy\n",
      "反义：sad\n",
      "\n",
      "原词：tall\n",
      "反义：short\n",
      "\n",
      "原词：big and huge adn massive and large and gigantic and tall and much much much much much much bigger then everyone\n",
      "反义：\n"
     ]
    }
   ],
   "source": [
    "#根据输入的提示词长度综合计算最终长度，智能截取或者添加提示词的示例\n",
    "\n",
    "from langchain.prompts import PromptTemplate\n",
    "from langchain.prompts import FewShotPromptTemplate\n",
    "from langchain.prompts.example_selector import LengthBasedExampleSelector\n",
    "\n",
    "#假设已经有这么多的提示词示例组：\n",
    "examples = [\n",
    "    {\"input\":\"happy\",\"output\":\"sad\"},\n",
    "    {\"input\":\"tall\",\"output\":\"short\"},\n",
    "    {\"input\":\"sunny\",\"output\":\"gloomy\"},\n",
    "    {\"input\":\"windy\",\"output\":\"calm\"},\n",
    "    {\"input\":\"高兴\",\"output\":\"悲伤\"}\n",
    "]\n",
    "\n",
    "#构造提示词模板\n",
    "example_prompt = PromptTemplate(\n",
    "    input_variables=[\"input\",\"output\"],\n",
    "    template=\"原词：{input}\\n反义：{output}\"\n",
    ")\n",
    "\n",
    "#调用长度示例选择器\n",
    "example_selector = LengthBasedExampleSelector(\n",
    "    #传入提示词示例组\n",
    "    examples=examples,\n",
    "    #传入提示词模板\n",
    "    example_prompt=example_prompt,\n",
    "    #设置格式化后的提示词最大长度\n",
    "    max_length=25,\n",
    "    #内置的get_text_length,如果默认分词计算方式不满足，可以自己扩展\n",
    "    #get_text_length:Callable[[str],int] = lambda x:len(re.split(\"\\n| \",x))\n",
    ")\n",
    "\n",
    "#使用小样本提示词模版来实现动态示例的调用\n",
    "dynamic_prompt = FewShotPromptTemplate(\n",
    "    example_selector=example_selector,\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=\"给出每个输入词的反义词\",\n",
    "    suffix=\"原词：{adjective}\\n反义：\",\n",
    "    input_variables=[\"adjective\"]\n",
    ")\n",
    "\n",
    "#小样本获得所有示例\n",
    "# print(dynamic_prompt.format(adjective=\"big\"))\n",
    "\n",
    "#如果输入长度很长，则最终输出会根据长度要求减少\n",
    "long_string = \"big and huge adn massive and large and gigantic and tall and much much much much much much bigger then everyone\"\n",
    "print(dynamic_prompt.format(adjective=long_string))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1579aaf1-b1db-47d0-beb4-da49199baae6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "给出每个输入词的反义词\n",
      "\n",
      "原词：高兴\n",
      "反义：悲伤\n",
      "\n",
      "原词：sunny\n",
      "反义：gloomy\n",
      "\n",
      "原词：难过\n",
      "反义：\n"
     ]
    }
   ],
   "source": [
    "from langchain.prompts.example_selector import MaxMarginalRelevanceExampleSelector\n",
    "from langchain.vectorstores import FAISS\n",
    "from langchain.prompts import FewShotPromptTemplate, PromptTemplate\n",
    "from langchain_community.embeddings import DashScopeEmbeddings  # 使用阿里云的嵌入模型\n",
    "import os\n",
    "\n",
    "\"\"\"\n",
    "根据输入相似度选择示例(最大边际相关性)\n",
    "    MMR是一种在信息检索中常用的方法，它的目标是在相关性和多样性之间找到一个平衡\n",
    "    MMR会首先找出与输入最相似（即余弦相似度最大）的样本\n",
    "    然后在迭代添加样本的过程中，对于与已选择样本过于接近（即相似度过高）的样本进行惩罚\n",
    "    MMR既能确保选出的样本与输入高度相关，又能保证选出的样本之间有足够的多样性\n",
    "    关注如何在相关性和多样性之间找到一个平衡\n",
    "使用阿里云嵌入模型需通过pip install dashscope安装DashScope库\n",
    "阿里云 DashScope 支持以下嵌入模型：\n",
    "    text-embedding-v1：通用文本嵌入\n",
    "    text-embedding-v2：升级版文本嵌入\n",
    "    text-embedding-async-v1：异步嵌入\n",
    "\"\"\"\n",
    "\n",
    "# 配置阿里云的 API 密钥\n",
    "api_key = \"sk-4e88cf4db3e14894bafaff606d296610\"\n",
    "\n",
    "# 假设已经有这么多的提示词示例组：\n",
    "examples = [\n",
    "    {\"input\": \"happy\", \"output\": \"sad\"},\n",
    "    {\"input\": \"tall\", \"output\": \"short\"},\n",
    "    {\"input\": \"sunny\", \"output\": \"gloomy\"},\n",
    "    {\"input\": \"windy\", \"output\": \"calm\"},\n",
    "    {\"input\": \"高兴\", \"output\": \"悲伤\"}\n",
    "]\n",
    "\n",
    "# 构造提示词模版\n",
    "example_prompt = PromptTemplate(\n",
    "    input_variables=[\"input\", \"output\"],\n",
    "    template=\"原词：{input}\\n反义：{output}\"\n",
    ")\n",
    "\n",
    "# 使用阿里云的嵌入模型\n",
    "embeddings = DashScopeEmbeddings(\n",
    "    model=\"text-embedding-v1\",  # 阿里云的嵌入模型\n",
    "    dashscope_api_key=api_key\n",
    ")\n",
    "\n",
    "# 调用MMR\n",
    "example_selector = MaxMarginalRelevanceExampleSelector.from_examples(\n",
    "    # 传入示例组\n",
    "    examples,\n",
    "    # 使用阿里云的嵌入来做相似性搜索\n",
    "    embeddings,\n",
    "    # 设置使用的向量数据库是什么\n",
    "    FAISS,\n",
    "    # 结果条数\n",
    "    k=2,\n",
    ")\n",
    "\n",
    "# 使用小样本模版\n",
    "mmr_prompt = FewShotPromptTemplate(\n",
    "    example_selector=example_selector,\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=\"给出每个输入词的反义词\",\n",
    "    suffix=\"原词：{adjective}\\n反义：\",\n",
    "    input_variables=[\"adjective\"]\n",
    ")\n",
    "\n",
    "# 当我们输入一个描述情绪的词语的时候，应该选择同样是描述情绪的一对示例组来填充提示词模版\n",
    "print(mmr_prompt.format(adjective=\"难过\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "40fb3d6d-30df-422d-abf4-a723e021710c",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\27727\\AppData\\Local\\Temp\\ipykernel_8484\\3889922690.py:22: LangChainDeprecationWarning: The class `HuggingFaceEmbeddings` was deprecated in LangChain 0.2.2 and will be removed in 1.0. An updated version of the class exists in the :class:`~langchain-huggingface package and should be used instead. To use it run `pip install -U :class:`~langchain-huggingface` and import as `from :class:`~langchain_huggingface import HuggingFaceEmbeddings``.\n",
      "  embeddings = HuggingFaceEmbeddings(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "给出每个输入词的反义词\n",
      "\n",
      "原词：高兴\n",
      "反义：悲伤\n",
      "\n",
      "原词：happy\n",
      "反义：sad\n",
      "\n",
      "原词：难过\n",
      "反义：\n"
     ]
    }
   ],
   "source": [
    "\"\"\"根据输入相似度选择示例(最大边际相关性)：\n",
    "MMR是一种在信息检索中常用的方法，它的目标是在相关性和多样性之间找到一个平衡\n",
    "MMR会首先找出与输入最相似（即余弦相似度最大）的样本\n",
    "然后在迭代添加样本的过程中，对于与已选择样本过于接近（即相似度过高）的样本进行惩罚\n",
    "MMR既能确保选出的样本与输入高度相关，又能保证选出的样本之间有足够的多样性\n",
    "关注如何在相关性和多样性之间找到一个平衡\n",
    "\"\"\"\n",
    "from langchain.prompts.example_selector import MaxMarginalRelevanceExampleSelector\n",
    "from langchain.vectorstores import FAISS\n",
    "from langchain.prompts import FewShotPromptTemplate, PromptTemplate\n",
    "from langchain_community.embeddings import HuggingFaceEmbeddings  # 使用HF嵌入模型\n",
    "\n",
    "# 假设已经有这么多的提示词示例组：\n",
    "examples = [\n",
    "    {\"input\": \"happy\", \"output\": \"sad\"},\n",
    "    {\"input\": \"tall\", \"output\": \"short\"},\n",
    "    {\"input\": \"sunny\", \"output\": \"gloomy\"},\n",
    "    {\"input\": \"windy\", \"output\": \"calm\"},\n",
    "    {\"input\": \"高兴\", \"output\": \"悲伤\"}\n",
    "]\n",
    "\n",
    "# 构造提示词模版\n",
    "example_prompt = PromptTemplate(\n",
    "    input_variables=[\"input\", \"output\"],\n",
    "    template=\"原词：{input}\\n反义：{output}\"\n",
    ")\n",
    "\n",
    "# 使用 HuggingFace 的嵌入模型（免费，无需API密钥）\n",
    "embeddings = HuggingFaceEmbeddings(\n",
    "    model_name=\"D:/ideaSpace/MyPython/models/all-MiniLM-L6-v2\"  # 轻量级嵌入模型\n",
    ")\n",
    "\n",
    "# 调用MMR\n",
    "example_selector = MaxMarginalRelevanceExampleSelector.from_examples(\n",
    "    examples,\n",
    "    embeddings,\n",
    "    FAISS,\n",
    "    k=2,\n",
    ")\n",
    "\n",
    "# 使用小样本模版\n",
    "mmr_prompt = FewShotPromptTemplate(\n",
    "    example_selector=example_selector,\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=\"给出每个输入词的反义词\",\n",
    "    suffix=\"原词：{adjective}\\n反义：\",\n",
    "    input_variables=[\"adjective\"]\n",
    ")\n",
    "\n",
    "print(mmr_prompt.format(adjective=\"难过\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "836a8432-0fac-484b-a83c-cc537244c7c4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "给出每个输入词的反义词\n",
      "\n",
      "原词: happy\n",
      "反义: sad\n",
      "\n",
      "原词: worried\n",
      "反义:\n"
     ]
    }
   ],
   "source": [
    "# 使用最大余弦相似度来检索相关示例，以使示例尽量符合输入\n",
    "from langchain.prompts.example_selector import SemanticSimilarityExampleSelector\n",
    "# from langchain.vectorstores import Chroma\n",
    "from langchain.vectorstores import FAISS\n",
    "# from langchain.embeddings import OpenAIEmbeddings\n",
    "from langchain_community.embeddings import DashScopeEmbeddings  # 使用阿里云的嵌入模型\n",
    "from langchain.prompts import FewShotPromptTemplate, PromptTemplate\n",
    "import os\n",
    "\n",
    "# 配置阿里云的 API 密钥\n",
    "api_key = \"sk-4e88cf4db3e14894bafaff606d296610\"\n",
    "\n",
    "example_prompt = PromptTemplate(\n",
    "    input_variables=[\"input\", \"output\"],\n",
    "    template=\"原词: {input}\\n反义: {output}\",\n",
    ")\n",
    "\n",
    "# Examples of a pretend task of creating antonyms.\n",
    "examples = [\n",
    "    {\"input\": \"happy\", \"output\": \"sad\"},\n",
    "    {\"input\": \"tall\", \"output\": \"short\"},\n",
    "    {\"input\": \"energetic\", \"output\": \"lethargic\"},\n",
    "    {\"input\": \"sunny\", \"output\": \"gloomy\"},\n",
    "    {\"input\": \"windy\", \"output\": \"calm\"},\n",
    "]\n",
    "\n",
    "# 使用阿里云的嵌入模型\n",
    "embeddings = DashScopeEmbeddings(\n",
    "    model=\"text-embedding-v1\",  # 阿里云的嵌入模型\n",
    "    dashscope_api_key=api_key\n",
    ")\n",
    "\n",
    "example_selector = SemanticSimilarityExampleSelector.from_examples(\n",
    "    # 传入示例组.\n",
    "    examples,\n",
    "    # 使用openAI嵌入来做相似性搜索\n",
    "    embeddings,\n",
    "    # 使用FAISS向量数据库来实现对相似结果的过程存储\n",
    "    FAISS,\n",
    "    # 结果条数\n",
    "    k=1,\n",
    ")\n",
    "\n",
    "#使用小样本提示词模板\n",
    "similar_prompt = FewShotPromptTemplate(\n",
    "    # 传入选择器和模板以及前缀后缀和输入变量\n",
    "    example_selector=example_selector,\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=\"给出每个输入词的反义词\",\n",
    "    suffix=\"原词: {adjective}\\n反义:\",\n",
    "    input_variables=[\"adjective\"],\n",
    ")\n",
    "\n",
    "# 输入一个形容感觉的词语，应该查找近似的 happy/sad 示例\n",
    "print(similar_prompt.format(adjective=\"worried\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0a515e99-441e-412f-a7b1-993e25182040",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "给出每个输入词的反义词\n",
      "\n",
      "原词: happy\n",
      "反义: sad\n",
      "\n",
      "原词: worried\n",
      "反义:\n"
     ]
    }
   ],
   "source": [
    "\"\"\"使用最大余弦相似度来检索相关示例，以使示例尽量符合输入\n",
    "根据输入相似度选择示例(最大余弦相似度)：\n",
    "    一种常见的相似度计算方法\n",
    "    它通过计算两个向量（在这里，向量可以代表文本、句子或词语）之间的余弦值来衡量它们的相似度\n",
    "    余弦值越接近1，表示两个向量越相似\n",
    "    主要关注的是如何准确衡量两个向量的相似度\n",
    "\"\"\"\n",
    "from langchain.prompts.example_selector import SemanticSimilarityExampleSelector\n",
    "# from langchain.vectorstores import Chroma\n",
    "from langchain.vectorstores import FAISS\n",
    "# from langchain.embeddings import OpenAIEmbeddings\n",
    "from langchain_community.embeddings import HuggingFaceEmbeddings  # 使用HF嵌入模型\n",
    "from langchain.prompts import FewShotPromptTemplate, PromptTemplate\n",
    "import os\n",
    "\n",
    "example_prompt = PromptTemplate(\n",
    "    input_variables=[\"input\", \"output\"],\n",
    "    template=\"原词: {input}\\n反义: {output}\",\n",
    ")\n",
    "\n",
    "# Examples of a pretend task of creating antonyms.\n",
    "examples = [\n",
    "    {\"input\": \"happy\", \"output\": \"sad\"},\n",
    "    {\"input\": \"tall\", \"output\": \"short\"},\n",
    "    {\"input\": \"energetic\", \"output\": \"lethargic\"},\n",
    "    {\"input\": \"sunny\", \"output\": \"gloomy\"},\n",
    "    {\"input\": \"windy\", \"output\": \"calm\"},\n",
    "]\n",
    "\n",
    "# 使用阿里云的嵌入模型\n",
    "embeddings = HuggingFaceEmbeddings(\n",
    "    model_name=\"D:/ideaSpace/MyPython/models/all-MiniLM-L6-v2\"  # 轻量级嵌入模型\n",
    ")\n",
    "\n",
    "example_selector = SemanticSimilarityExampleSelector.from_examples(\n",
    "    # 传入示例组.\n",
    "    examples,\n",
    "    # 使用openAI嵌入来做相似性搜索\n",
    "    embeddings,\n",
    "    # 使用FAISS向量数据库来实现对相似结果的过程存储\n",
    "    FAISS,\n",
    "    # 结果条数\n",
    "    k=1,\n",
    ")\n",
    "\n",
    "#使用小样本提示词模板\n",
    "similar_prompt = FewShotPromptTemplate(\n",
    "    # 传入选择器和模板以及前缀后缀和输入变量\n",
    "    example_selector=example_selector,\n",
    "    example_prompt=example_prompt,\n",
    "    prefix=\"给出每个输入词的反义词\",\n",
    "    suffix=\"原词: {adjective}\\n反义:\",\n",
    "    input_variables=[\"adjective\"],\n",
    ")\n",
    "\n",
    "# 输入一个形容感觉的词语，应该查找近似的 happy/sad 示例\n",
    "print(similar_prompt.format(adjective=\"worried\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ef37715-3f9a-47bf-b261-7ccdbc16ee4a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "rag_learn",
   "language": "python",
   "name": "rag_learn"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
